package com.dhcc.DRGsHosp.infra.util;

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.poi.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;

import sun.misc.BASE64Decoder;  
  
/** 
 * 适用于word 2007 
 * poi 版本 3.7 
 */  
public class WordUtil {  
  
    /** 
     * 根据指定的参数值、模板，生成 word 文档 
     * @param param 需要替换的变量 
     * @param template 模板 
     */  
    public static CustomXWPFDocument generateWord(Map<String, Object> param, String template) {  
        CustomXWPFDocument doc = null;  
        try {  
            OPCPackage pack = POIXMLDocument.openPackage(template);  
            doc = new CustomXWPFDocument(pack);  
            if (param != null && param.size() > 0) {  
                  
          	   //处理表格  
                Iterator<XWPFTable> it = doc.getTablesIterator();  
                while (it.hasNext()) {  
                    XWPFTable table = it.next();  
                    List<XWPFTableRow> rows = table.getRows();
                    for (XWPFTableRow row : rows) {  
                        List<XWPFTableCell> cells = row.getTableCells();  
                        for (XWPFTableCell cell : cells) {  
                            List<XWPFParagraph> paragraphListTable =  cell.getParagraphs();
                            processParagraphs(paragraphListTable, param, doc);
                        }  
                    }  
                } 
                //处理段落  
                List<XWPFParagraph> paragraphList = doc.getParagraphs();  
                processParagraphs(paragraphList, param, doc);  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return doc;  
    }  
     /** 
     * 处理段落 
     * @param paragraphList 
     */
    public static void processParagraphs(List<XWPFParagraph> paragraphList,Map<String, Object> param,CustomXWPFDocument doc) throws Exception{  
        if(paragraphList != null && paragraphList.size() > 0 &&param.size()>0){  
            for(XWPFParagraph paragraph:paragraphList){  
                List<XWPFRun> runs = paragraph.getRuns();
                String text="";
                for (int i = 0; i < runs.size(); i++) {
                	   XWPFRun run=(XWPFRun) (runs.get(i)==null?"":runs.get(i));
                	    text = run.getText(0);  
                       if(text != null && text.contains("${")){  
                    	  if(text != null){  
                          boolean isSetText = false;  
                          String key ="";
                          text=text.replace("${", "");
                          text=text.replace("}", "");
                          Object obj= param.get(text);
                          if (obj!=null && obj instanceof Map) {//图片替换  
                        	  key=text;
                        	  isSetText = true;  
                              text = text.replace(key, "");  
                              Map pic = (Map)obj;
                              int width = Integer.parseInt(pic.get("width").toString());  
                              int height = Integer.parseInt(pic.get("height").toString());  
                              int picType = getPictureType(pic.get("type").toString());  
                              byte[] byteArray = (byte[]) pic.get("content");  
                              ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);  
                              try {  
                              	  doc.addPictureData(byteInputStream,picType);  
                                  doc.createPicture(doc.getAllPictures().size()-1, width , height,paragraph);  
                              } catch (Exception e) {
                                  e.printStackTrace();  
                              }  
                              byteInputStream.close();
                          } else if (obj!=null ){
                         	 isSetText = true;  
                         	 text=text.replace(text, obj==null?"":obj+"");  
                           }
                          
                          if(isSetText){
                              run.setText(text,0);  
                          }  
                         
				       }
                    }  
               }  
                }
        }  
    }  
    /** 
     * 根据图片类型，取得对应的图片类型代码 
     * @param picType 
     * @return int 
     */  
    private static int getPictureType(String picType){  
        int res = CustomXWPFDocument.PICTURE_TYPE_PICT;  
        if(picType != null){  
            if(picType.equalsIgnoreCase("png")){  
                res = CustomXWPFDocument.PICTURE_TYPE_PNG;  
            }else if(picType.equalsIgnoreCase("dib")){  
                res = CustomXWPFDocument.PICTURE_TYPE_DIB;  
            }else if(picType.equalsIgnoreCase("emf")){  
                res = CustomXWPFDocument.PICTURE_TYPE_EMF;  
            }else if(picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")){  
                res = CustomXWPFDocument.PICTURE_TYPE_JPEG;  
            }else if(picType.equalsIgnoreCase("wmf")){  
                res = CustomXWPFDocument.PICTURE_TYPE_WMF;  
            }  
        }  
        return res;  
    }  
    /** 
     * 将输入流中的数据写入字节数组 
     * @param in 
     * @return 
     */  
    public static byte[] inputStream2ByteArray(InputStream in,boolean isClose){  
        byte[] byteArray = null;  
        try {  
            int total = in.available();  
            byteArray = new byte[total];  
            in.read(byteArray);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally{  
            if(isClose){  
                try {  
                    in.close();  
                } catch (Exception e2) {  
                    System.out.println("关闭流失败");  
                }  
            }  
        }  
        return byteArray;  
    }  
    
    //base64字符串转化成图片  
    public static boolean GenerateImage(String imgStr, String root, String imgName)
    {   //对字节数组字符串进行Base64解码并生成图片
        if (imgStr == null) //图像数据为空
            return false; 
        BASE64Decoder decoder = new BASE64Decoder();
        try
        {
            //Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);  
            for(int i=0;i<b.length;++i)  
            {  
                if(b[i]<0)  
                {//调整异常数据  
                    b[i]+=256;  
                }  
            }  
            //生成jpeg图片  
            String imgFilePath = root+imgName+".jpg";//新生成的图片  
            OutputStream out = new FileOutputStream(imgFilePath);      
            out.write(b);  
            out.flush();  
            out.close();  
            return true;  
        }   
        catch (Exception e)   
        {  
            return false;  
        }  
    }  
    
    /** 
     * @Description: 按模版行样式填充数据,暂未实现特殊样式填充(如列合并)，只能用于普通样式(如段落间距 缩进 字体 对齐) 
     * @param resultList 填充数据 
     * @param tableRowSize 模版表格行数 取第一个行数相等列数相等的表格填充 
     * @param isDelTmpRow 是否删除模版行 
     */  
    //TODO 数据行插到模版行下面，没有实现指定位置插入  
    public static void insertValueToTable(XWPFDocument doc,  
            List<List<String>> resultList,int tableRowSize,boolean isDelTmpRow) throws Exception {  
        Iterator<XWPFTable> iterator = doc.getTablesIterator();  
        XWPFTable table = null;  
        List<XWPFTableRow> rows=null;  
        List<XWPFTableCell> cells=null;  
        List<XWPFTableCell> tmpCells=null;//模版列  
        XWPFTableRow tmpRow=null;//匹配用  
        XWPFTableCell tmpCell=null;//匹配用  
        boolean flag=false;//是否找到表格  
        while (iterator.hasNext()) {  
            table = iterator.next();  
            rows = table.getRows();  
            if(rows.size()==tableRowSize){  
                tmpRow=rows.get(tableRowSize-1);  
                cells =tmpRow.getTableCells();  
                if(cells.size()==resultList.get(0).size()){  
                    flag=true;  
                    break;  
                }  
            }  
        }  
        if(!flag){  
            return;  
        }  
        tmpCells=tmpRow.getTableCells();  
        for(int i=0,len=resultList.size();i<len;i++){  
            XWPFTableRow row=table.createRow();  
            row.setHeight(tmpRow.getHeight());  
            List<String> list=resultList.get(i);  
            cells=row.getTableCells();  
            //插入的行会填充与表格第一行相同的列数  
            for(int k=0,klen=cells.size();k<klen;k++){  
                tmpCell=tmpCells.get(k);  
                XWPFTableCell cell=cells.get(k);  
                setCellText(tmpCell, cell, list.get(k));  
            }  
            //继续写剩余的列  
            for(int j=cells.size(),jlen=list.size();j<jlen;j++){  
                tmpCell=tmpCells.get(j);  
                XWPFTableCell cell=row.addNewTableCell();  
                setCellText(tmpCell, cell, list.get(j));  
            }  
        }  
        //删除模版行  
        if(isDelTmpRow){  
        	for (int i = 0; i < tableRowSize-1; i++) {
        		table.removeRow(tableRowSize-i-1);
			}
              
        }  
    }  
      //给表格单元格赋值
    public static  void setCellText(XWPFTableCell tmpCell,XWPFTableCell cell,String text) throws Exception{  
        CTTc cttc2 = tmpCell.getCTTc();  
        CTTcPr ctPr2=cttc2.getTcPr();  
          
        CTTc cttc = cell.getCTTc();  
        CTTcPr ctPr = cttc.addNewTcPr();  
        cell.setColor(tmpCell.getColor());  
        if(ctPr2.getTcW()!=null){  
            ctPr.addNewTcW().setW(ctPr2.getTcW().getW());  
        }  
        if(ctPr2.getVAlign()!=null){  
            ctPr.addNewVAlign().setVal(ctPr2.getVAlign().getVal());  
        }  
        if(cttc2.getPList().size()>0){  
            CTP ctp=cttc2.getPList().get(0);  
            if(ctp.getPPr()!=null){  
                if(ctp.getPPr().getJc()!=null){  
                    cttc.getPList().get(0).addNewPPr().addNewJc().setVal(ctp.getPPr().getJc().getVal());  
                }  
            }  
        }  
          
        if(ctPr2.getTcBorders()!=null){  
            ctPr.setTcBorders(ctPr2.getTcBorders());  
        }  
          
        XWPFParagraph tmpP=tmpCell.getParagraphs().get(0);  
        XWPFParagraph cellP=cell.getParagraphs().get(0);  
        XWPFRun tmpR =null;  
        if(tmpP.getRuns()!=null&&tmpP.getRuns().size()>0){  
            tmpR=tmpP.getRuns().get(0);  
        }
        XWPFRun cellR = cellP.createRun();  
        cellR.setText(text); 
        boolean resultInt=(text==null?"":text.toString().trim()).matches("([1-9]+[0-9]*|0)(\\.[\\d]+)?");
        boolean resultStr=(text==null?"":text.toString().trim()).matches("[a-zA-Z]+");
        if(resultInt==true||resultStr==true){
        	cellR.setFontSize(11);  
        	cellR.setFontFamily("Times New Roman"); 
        }else{
        	cellR.setFontSize(11);  
        	cellR.setFontFamily("SimSun"); 
        }
        
        //复制字体信息  
        if(tmpR!=null){
            cellR.setBold(tmpR.isBold());  
            cellR.setItalic(tmpR.isItalic());  
            cellR.setStrike(tmpR.isStrike());  
            cellR.setUnderline(tmpR.getUnderline());  
            cellR.setColor(tmpR.getColor());  
            cellR.setTextPosition(tmpR.getTextPosition());  
            if(tmpR.getFontSize()!=-1){  
                cellR.setFontSize(11);  
            }  
            if(tmpR.getFontFamily()!=null){
                cellR.setFontFamily("Times New Roman"); 
            }  
            if(tmpR.getCTR()!=null){  
                if(tmpR.getCTR().isSetRPr()){  
                    CTRPr tmpRPr =tmpR.getCTR().getRPr();  
                    if(tmpRPr.isSetRFonts()){  
                        CTFonts tmpFonts=tmpRPr.getRFonts();  
                        CTRPr cellRPr=cellR.getCTR().isSetRPr() ? cellR.getCTR().getRPr() : cellR.getCTR().addNewRPr();  
                        CTFonts cellFonts = cellRPr.isSetRFonts() ? cellRPr.getRFonts() : cellRPr.addNewRFonts();  
                        cellFonts.setAscii(tmpFonts.getAscii());  
                        cellFonts.setAsciiTheme(tmpFonts.getAsciiTheme());  
                        cellFonts.setCs(tmpFonts.getCs());  
                        cellFonts.setCstheme(tmpFonts.getCstheme());  
                        cellFonts.setEastAsia(tmpFonts.getEastAsia());  
                        cellFonts.setEastAsiaTheme(tmpFonts.getEastAsiaTheme());  
                        cellFonts.setHAnsi(tmpFonts.getHAnsi());  
                        cellFonts.setHAnsiTheme(tmpFonts.getHAnsiTheme());  
                    }  
                }  
            }  
        }  
        //复制段落信息  
        cellP.setAlignment(tmpP.getAlignment());  
        cellP.setVerticalAlignment(tmpP.getVerticalAlignment());  
        cellP.setBorderBetween(tmpP.getBorderBetween());  
        cellP.setBorderBottom(tmpP.getBorderBottom());  
        cellP.setBorderLeft(tmpP.getBorderLeft());  
        cellP.setBorderRight(tmpP.getBorderRight());  
        cellP.setBorderTop(tmpP.getBorderTop());  
        cellP.setPageBreak(tmpP.isPageBreak());  
        if(tmpP.getCTP()!=null){  
            if(tmpP.getCTP().getPPr()!=null){  
                CTPPr tmpPPr = tmpP.getCTP().getPPr();  
                CTPPr cellPPr = cellP.getCTP().getPPr() != null ? cellP.getCTP().getPPr() : cellP.getCTP().addNewPPr();  
                //复制段落间距信息  
                CTSpacing tmpSpacing =tmpPPr.getSpacing();  
                if(tmpSpacing!=null){  
                    CTSpacing cellSpacing= cellPPr.getSpacing()!=null?cellPPr.getSpacing():cellPPr.addNewSpacing();  
                    if(tmpSpacing.getAfter()!=null){  
                        cellSpacing.setAfter(tmpSpacing.getAfter());  
                    }  
                    if(tmpSpacing.getAfterAutospacing()!=null){  
                        cellSpacing.setAfterAutospacing(tmpSpacing.getAfterAutospacing());  
                    }  
                    if(tmpSpacing.getAfterLines()!=null){  
                        cellSpacing.setAfterLines(tmpSpacing.getAfterLines());  
                    }  
                    if(tmpSpacing.getBefore()!=null){  
                        cellSpacing.setBefore(tmpSpacing.getBefore());  
                    }  
                    if(tmpSpacing.getBeforeAutospacing()!=null){  
                        cellSpacing.setBeforeAutospacing(tmpSpacing.getBeforeAutospacing());  
                    }  
                    if(tmpSpacing.getBeforeLines()!=null){  
                        cellSpacing.setBeforeLines(tmpSpacing.getBeforeLines());  
                    }  
                    if(tmpSpacing.getLine()!=null){  
                        cellSpacing.setLine(tmpSpacing.getLine());  
                    }  
                    if(tmpSpacing.getLineRule()!=null){  
                        cellSpacing.setLineRule(tmpSpacing.getLineRule());  
                    }  
                }  
                //复制段落缩进信息  
                CTInd tmpInd=tmpPPr.getInd();  
                if(tmpInd!=null){  
                    CTInd cellInd=cellPPr.getInd()!=null?cellPPr.getInd():cellPPr.addNewInd();  
                    if(tmpInd.getFirstLine()!=null){  
                        cellInd.setFirstLine(tmpInd.getFirstLine());  
                    }  
                    if(tmpInd.getFirstLineChars()!=null){  
                        cellInd.setFirstLineChars(tmpInd.getFirstLineChars());  
                    }  
                    if(tmpInd.getHanging()!=null){  
                        cellInd.setHanging(tmpInd.getHanging());  
                    }  
                    if(tmpInd.getHangingChars()!=null){  
                        cellInd.setHangingChars(tmpInd.getHangingChars());  
                    }  
                    if(tmpInd.getLeft()!=null){  
                        cellInd.setLeft(tmpInd.getLeft());  
                    }  
                    if(tmpInd.getLeftChars()!=null){  
                        cellInd.setLeftChars(tmpInd.getLeftChars());  
                    }  
                    if(tmpInd.getRight()!=null){  
                        cellInd.setRight(tmpInd.getRight());  
                    }  
                    if(tmpInd.getRightChars()!=null){  
                        cellInd.setRightChars(tmpInd.getRightChars());  
                    }  
                }  
            }  
        }  
    }  
}  
